package mybatis.generator.support.parse;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by huangdachao on 2018/6/17 16:58.
 */
public class TableColumn implements Comparable<TableColumn> {
    // 表名模式
    public static final Pattern TABLE_COLUMN_PATTERN = Pattern.compile("\\$\\(([a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)?)\\).([a-zA-Z_][a-zA-Z0-9_]*)");
    // 实体类字段模式
    public static final Pattern ENTITY_FIELD_TABLE_COLUMN_PATTERN = Pattern.compile("\\$\\[([a-zA-Z_][a-zA-Z0-9_]*)]");
    public String table;
    public String tblAlias; // 表别名，用于多态表自关联
    public String column;

    public TableColumn() {
        this("", "", "");
    }

    public TableColumn(String table, String column) {
        this.table = table;
        this.tblAlias = "";
        this.column = column;
    }

    public TableColumn(Table table, String column) {
        this.table = table.table;
        this.tblAlias = table.alias;
        this.column = column;
    }

    public TableColumn(String table, String tblAlias, String column) {
        this.table = table;
        this.tblAlias = tblAlias == null ? "" : tblAlias;
        this.column = column;
    }

    public static List<TableColumn> parse(String str, EntityMeta em) {
        Matcher matcher = TABLE_COLUMN_PATTERN.matcher(str);
        List<TableColumn> list = new ArrayList<>();
        while (matcher.find()) {
            String[] arr = matcher.group(1).split("\\.");
            list.add(new TableColumn(arr[0], arr.length > 1 ? arr[1] : "", matcher.group(3)));
        }

        matcher = ENTITY_FIELD_TABLE_COLUMN_PATTERN.matcher(str);
        while (matcher.find()) {
            String field = matcher.group(1);
            TableColumn tc = em.getFieldsMap().get(field);
            if (tc != null) {
                list.add(tc);
            }
        }
        return list;
    }

    public Table toTable() {
        return new Table(this.table, this.tblAlias);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof TableColumn)) return false;
        TableColumn that = (TableColumn) o;
        return Objects.equals(table, that.table) &&
            Objects.equals(tblAlias, that.tblAlias) &&
            Objects.equals(column, that.column);
    }

    @Override
    public int hashCode() {
        return Objects.hash(table, tblAlias, column);
    }

    @Override
    public int compareTo(TableColumn o) {
        int result = this.table.compareTo(o.table);
        if (result == 0) {
            result = this.tblAlias.compareTo(o.tblAlias);
        }
        if (result == 0) {
            result = this.column.compareTo(o.column);
        }
        return result;
    }
}
